package com.zhilianbao.leyaogo.http.callback;

import com.bql.convenientlog.CLog;
import com.bql.utils.AESOperator;
import com.bql.utils.DateUtils;
import com.zhilianbao.leyaogo.constants.KeyConfig;
import com.zhilianbao.okhttputils.callback.Callback;
import com.zhilianbao.okhttputils.model.JsonParams;
import com.zhilianbao.okhttputils.model.SortObject;
import com.zhilianbao.okhttputils.request.BaseRequest;
import com.zhilianbao.okhttputils.request.PostRequest;

import org.json.JSONObject;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.concurrent.ConcurrentHashMap;

/**
 * ClassName: CommonCallback <br>
 * Description: 添加请求头参数 以及 请求参数加密<br>
 * Author: Cyarie <br>
 * Created: 2016/7/20 14:46 <br>
 * Update Time：<br>
 * Update Description：<br>
 */
public abstract class CommonCallback<T> extends Callback<T> {

    @Override
    public void onBefore(BaseRequest request) {
        super.onBefore(request);
        String timestamp = DateUtils.format(System.currentTimeMillis(), DateUtils.DATE_TIME_FORMAT_S);
        JsonParams jsonParams = new JsonParams();
        jsonParams.put("apiKey", KeyConfig.LE_API_KEY);
        jsonParams.put("timestamp", timestamp);
        if (request.isPostForm()) {
            if (request.getParams().urlParamsMap != null && !request.getParams().urlParamsMap.isEmpty()) {
                for (ConcurrentHashMap.Entry<String, List<String>> entry : request.getParams().urlParamsMap.entrySet()) {
                    jsonParams.put(entry.getKey(), entry.getValue().get(0));
                }
            }
        } else {
            jsonParams.put("bizContent", request.getJsonParams());
        }

        //对所有参数进行md5签名
        Map<String, Object> paramsMap = new HashMap<>();
        if (request.isPostForm()) {
            for (Map.Entry<String, Object> stringObjectEntry : getParamsMap(jsonParams.toJson()).entrySet()) {
                paramsMap.put(stringObjectEntry.getKey(), stringObjectEntry.getValue());
            }
        } else {
            paramsMap.put("apiKey", KeyConfig.LE_API_KEY);
            paramsMap.put("timestamp", timestamp);
            if (request.getJsonParams() != null) {
                paramsMap.put("bizContent", sortParams(getParamsMap(request.getJsonParams().toJson())));
            }

        }
        String sign = generateSign(paramsMap, KeyConfig.LE_SECRET_KEY);
        jsonParams.put("sign", sign);
        if (request.isPostForm()) {
            paramsMap.put("sign", sign);
            request.getParams().urlParamsMap.clear();
            for (Map.Entry<String, Object> stringObjectEntry : paramsMap.entrySet()) {
                request.getParams().put(stringObjectEntry.getKey(), (String) stringObjectEntry.getValue());
            }
        }
        if (request instanceof PostRequest && !request.isPostForm()) {
            ((PostRequest) request).upJson(jsonParams.toString());
            CLog.json("LogInterceptor", jsonParams.toString());
        }

    }


    /**
     * 获取请求参数Map数组
     *
     * @param jsonObject
     * @return
     */
    private Map<String, Object> getParamsMap(JSONObject jsonObject) {
        Map<String, Object> sMap = new HashMap<>();
        Iterator it = jsonObject.keys();
        while (it.hasNext()) {
            String key = (String) it.next();
            Object value = jsonObject.opt(key);
            sMap.put(key, value);
        }
        return sMap;
    }

    /**
     * 参数生成签名
     *
     * @param params    参数
     * @param secretKey 密钥
     * @return
     */
    private String generateSign(Map<String, Object> params, String secretKey) {
        SortedMap<String, Object> sMap = new TreeMap<>(params);
        StringBuffer sb = new StringBuffer();
        for (Map.Entry<String, Object> m : sMap.entrySet()) {
            sb.append(m.getKey()).append("=").append(m.getValue()).append("&");
        }
        String paramStr = sb.append("key=").append(secretKey).toString();
        String md5Str = AESOperator.encodeMD5(paramStr);
        return md5Str.toUpperCase();
    }


    /**
     * 参数排序
     *
     * @param params
     * @return
     */
    private JSONObject sortParams(Map<String, Object> params) {
        SortObject jsonObject = null;
        try {
            jsonObject = new SortObject();
            SortedMap<String, Object> sMap = new TreeMap<>(params);
            for (Map.Entry<String, Object> m : sMap.entrySet()) {
                jsonObject.put(m.getKey(), m.getValue());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return jsonObject;
    }
}
